"""
代理帮助类 - 用于绕过地区限制
"""

import aiohttp
import asyncio
import random
from typing import Dict, List, Optional
from config.logging_config import ProjectLoggers

logger = ProjectLoggers.get_service_logger()

class ProxyHelper:
    """代理帮助类"""
    
    def __init__(self):
        # 免费代理池（测试用）
        self.free_proxies = [
            # 美国代理
            "8.8.8.8:3128",
            "1.1.1.1:80",
            # 日本代理
            "133.18.234.13:80",
            # 新加坡代理
            "159.138.169.166:8080",
        ]
        
        # 用户代理池
        self.user_agents = [
            # Chrome (Windows)
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
            # Chrome (Mac)
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
            # Firefox (Windows)
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/121.0",
            # Safari (Mac)
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15",
            # Edge (Windows)
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
            # iOS Safari
            "Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1",
            # Android Chrome
            "Mozilla/5.0 (Linux; Android 10; SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36"
        ]
    
    def get_random_user_agent(self) -> str:
        """获取随机User-Agent"""
        return random.choice(self.user_agents)
    
    def get_random_proxy(self) -> Optional[str]:
        """获取随机代理"""
        if self.free_proxies:
            return random.choice(self.free_proxies)
        return None
    
    async def test_proxy(self, proxy: str, timeout: int = 10) -> bool:
        """测试代理可用性"""
        try:
            proxy_url = f"http://{proxy}"
            connector = aiohttp.TCPConnector(ssl=False)
            
            async with aiohttp.ClientSession(
                connector=connector,
                timeout=aiohttp.ClientTimeout(total=timeout)
            ) as session:
                async with session.get(
                    "http://httpbin.org/ip",
                    proxy=proxy_url,
                    headers={'User-Agent': self.get_random_user_agent()}
                ) as response:
                    if response.status == 200:
                        data = await response.json()
                        logger.info(f"代理 {proxy} 测试成功，IP: {data.get('origin', 'unknown')}")
                        return True
                    else:
                        logger.warning(f"代理 {proxy} 测试失败，状态码: {response.status}")
                        return False
                        
        except Exception as e:
            logger.warning(f"代理 {proxy} 测试失败: {str(e)}")
            return False
    
    async def get_working_proxy(self) -> Optional[str]:
        """获取可用的代理"""
        for proxy in self.free_proxies:
            if await self.test_proxy(proxy):
                return proxy
        
        logger.warning("没有找到可用的代理")
        return None
    
    def get_advanced_headers(self, target_region: str = "US") -> Dict[str, str]:
        """获取高级请求头"""
        base_headers = {
            'User-Agent': self.get_random_user_agent(),
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
            'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7',
            'Accept-Encoding': 'gzip, deflate, br',
            'Cache-Control': 'no-cache',
            'Pragma': 'no-cache',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'none',
            'Sec-Fetch-User': '?1',
            'Upgrade-Insecure-Requests': '1',
        }
        
        # 根据目标地区添加特定头部
        if target_region == "US":
            base_headers.update({
                'Accept-Language': 'en-US,en;q=0.9',
                'CF-IPCountry': 'US',
                'X-Forwarded-For': '8.8.8.8',
            })
        elif target_region == "JP":
            base_headers.update({
                'Accept-Language': 'ja-JP,ja;q=0.9,en;q=0.8',
                'CF-IPCountry': 'JP',
            })
        elif target_region == "SG":
            base_headers.update({
                'Accept-Language': 'en-SG,en;q=0.9,zh;q=0.8',
                'CF-IPCountry': 'SG',
            })
        
        return base_headers
    
    def get_youtube_specific_headers(self, client_type: str = "web") -> Dict[str, str]:
        """获取YouTube专用请求头"""
        if client_type == "ios":
            return {
                'User-Agent': 'com.google.ios.youtube/19.29.1 (iPhone14,3; U; CPU iOS 16_0 like Mac OS X)',
                'X-Goog-Api-Key': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8',
                'X-Youtube-Client-Name': '5',
                'X-Youtube-Client-Version': '19.29.1',
                'Accept': '*/*',
                'Accept-Language': 'en-US,en;q=0.9',
                'Accept-Encoding': 'gzip, deflate, br',
                'Origin': 'https://www.youtube.com',
                'Referer': 'https://www.youtube.com/',
            }
        elif client_type == "android":
            return {
                'User-Agent': 'com.google.android.youtube/17.31.35 (Linux; U; Android 11) gzip',
                'X-Goog-Api-Key': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8',
                'X-Youtube-Client-Name': '3',
                'X-Youtube-Client-Version': '17.31.35',
                'Accept': '*/*',
                'Accept-Language': 'en-US,en;q=0.9',
                'Accept-Encoding': 'gzip, deflate',
                'Origin': 'https://www.youtube.com',
                'Referer': 'https://www.youtube.com/',
            }
        else:  # web
            return {
                'User-Agent': self.get_random_user_agent(),
                'Accept': '*/*',
                'Accept-Language': 'en-US,en;q=0.9',
                'Accept-Encoding': 'gzip, deflate, br',
                'Origin': 'https://www.youtube.com',
                'Referer': 'https://www.youtube.com/',
                'Sec-Fetch-Dest': 'empty',
                'Sec-Fetch-Mode': 'cors',
                'Sec-Fetch-Site': 'same-origin',
                'X-Youtube-Client-Name': '1',
                'X-Youtube-Client-Version': '2.20231219.04.00',
            }
    
    async def make_request_with_proxy(
        self, 
        url: str, 
        method: str = "GET",
        headers: Optional[Dict[str, str]] = None,
        proxy: Optional[str] = None,
        timeout: int = 30
    ) -> Optional[Dict]:
        """使用代理发送请求"""
        
        if not proxy:
            proxy = await self.get_working_proxy()
        
        if not headers:
            headers = self.get_advanced_headers()
        
        try:
            proxy_url = f"http://{proxy}" if proxy else None
            connector = aiohttp.TCPConnector(ssl=False)
            
            async with aiohttp.ClientSession(
                connector=connector,
                timeout=aiohttp.ClientTimeout(total=timeout)
            ) as session:
                
                kwargs = {
                    'headers': headers,
                    'ssl': False
                }
                
                if proxy_url:
                    kwargs['proxy'] = proxy_url
                
                async with session.request(method, url, **kwargs) as response:
                    if response.status == 200:
                        if 'application/json' in response.headers.get('content-type', ''):
                            return await response.json()
                        else:
                            return {'text': await response.text()}
                    else:
                        logger.warning(f"请求失败，状态码: {response.status}")
                        return None
                        
        except Exception as e:
            logger.error(f"代理请求失败: {str(e)}")
            return None

# 全局代理助手实例
proxy_helper = ProxyHelper() 